package gd.qaq.blue.locationleader.util;

import gd.qaq.blue.locationleader.entity.TargetLocation;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.entity.Player;

import java.sql.DatabaseMetaData;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

@SuppressWarnings("all")
public class JDBCUtils extends SqlHelper {
    public JDBCUtils(final String dbFileName) {
        super(dbFileName);
        this.createDB();
    }

    public boolean createDB() {
        try {
            final DatabaseMetaData dbMetaData = this.conn.getMetaData();
            final String[] types = {"TABLE"};
            final ResultSet tabs = dbMetaData.getTables(null, null, "tb_locations", types);
            if (tabs.next()) {
                return true;
            }
            final String sql = "CREATE TABLE `tb_locations` ( " +
                    "  `id` integer PRIMARY KEY autoincrement,  " +
                    "  `locationName` varchar NOT NULL,\n" +
                    "  `worldName` varchar NOT NULL,\n" +
                    "  `locationX` varchar NOT NULL,\n" +
                    "  `locationY` varchar NOT NULL,\n" +
                    "  `locationZ` varchar NOT NULL,\n" +
                    "  `locationYaw` varchar NOT NULL,\n" +
                    "  `locationPitch` varchar NOT NULL)";
            final String sql2 = "CREATE TABLE `tb_playerCaches` ( " +
                    "  `id` integer PRIMARY KEY autoincrement,  " +
                    "  `playerUUID` varchar NOT NULL,\n" +
                    "  `locationName` varchar NOT NULL,\n" +
                    "  `worldName` varchar NOT NULL,\n" +
                    "  `locationX` varchar NOT NULL,\n" +
                    "  `locationY` varchar NOT NULL,\n" +
                    "  `locationZ` varchar NOT NULL,\n" +
                    "  `locationYaw` varchar NOT NULL,\n" +
                    "  `locationPitch` varchar NOT NULL)";
            this.query(sql).execute();
            this.query(sql2).execute();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return false;
    }

    public boolean add(String UUID, final String locationName, final Location location) {
        final String sql = "INSERT INTO tb_playerCaches (locationName,worldName,locationX,locationY,locationZ,locationYaw,locationPitch,playerUUID) values (?,?,?,?,?,?,?,?);";
        try {
            final PreparedStatement pre = this.query(sql);
            pre.setString(1, locationName);
            pre.setString(2, location.getWorld().getName());
            pre.setString(3, String.valueOf(location.getX()));
            pre.setString(4, String.valueOf(location.getY()));
            pre.setString(5, String.valueOf(location.getZ()));
            pre.setString(6, String.valueOf(location.getYaw()));
            pre.setString(7, String.valueOf(location.getPitch()));
            pre.setString(8, UUID);
            if (pre.executeUpdate() == 0) {
                return false;
            }
        } catch (SQLException e) {
//            e.printStackTrace();
            return false;
        }
        return true;
    }

    public Map getAllCaches() {
        final String sql = "SELECT * FROM tb_playerCaches";
        ResultSet rs = null;
        final Map commandInfo = new HashMap();
        try {
            final PreparedStatement pre = this.query(sql);
            rs = pre.executeQuery();
            while (rs.next()) {
                TargetLocation targetLocation = new TargetLocation();
//                commandInfo.put("locationName", rs.getInt("locationName"));
                Location location = new Location(Bukkit.getWorld(rs.getString("worldName")),
                        Double.parseDouble(rs.getString("locationX")),
                        Double.parseDouble(rs.getString("locationY")),
                        Double.parseDouble(rs.getString("locationZ")),
                        Float.parseFloat(rs.getString("locationYaw")),
                        Float.parseFloat(rs.getString("locationPitch")));
                commandInfo.put("location", location);
                targetLocation.setLocationName(rs.getString("locationName"));
                targetLocation.setLocation(location);
                commandInfo.put(rs.getString("playerUUID"), targetLocation);
            }
        } catch (Exception e) {
//            e.printStackTrace();
            return null;
        }
        return commandInfo;
    }

    public Map get(final Player player) {
        final String sql = "SELECT * FROM tb_playerCaches WHERE playerUUID = ?";
        ResultSet rs = null;
        final Map commandInfo = new HashMap();
        try {
            final PreparedStatement pre = this.query(sql);
            pre.setString(1, player.getUniqueId().toString());
            rs = pre.executeQuery();
            while (rs.next()) {
                commandInfo.put("locationName", rs.getString("locationName"));
                Location location = new Location(Bukkit.getWorld(rs.getString("worldName")),
                        Double.parseDouble(rs.getString("locationX")),
                        Double.parseDouble(rs.getString("locationY")),
                        Double.parseDouble(rs.getString("locationZ")),
                        Float.parseFloat(rs.getString("locationYaw")),
                        Float.parseFloat(rs.getString("locationPitch")));
                commandInfo.put("location", location);
                commandInfo.put("playerUUID", rs.getString("playerUUID"));
            }
        } catch (Exception e) {
//            e.printStackTrace();
            return null;
        }
        return commandInfo;
    }

    public boolean remove(final Player player) {
        final String sql = "DELETE FROM tb_playerCaches WHERE playerUUID = ?";
        try {
            final PreparedStatement pre = this.query(sql);
            pre.setString(1, player.getUniqueId().toString());
            if (pre.executeUpdate() == 0) {
                return false;
            }
        } catch (SQLException e) {
//            e.printStackTrace();
            return false;
        }
        return true;
    }

    public boolean add(final String locationName, final Location location) {
        final String sql = "INSERT INTO tb_locations (locationName,worldName,locationX,locationY,locationZ,locationYaw,locationPitch) values (?,?,?,?,?,?,?);";
        try {
            final PreparedStatement pre = this.query(sql);
            pre.setString(1, locationName);
            pre.setString(2, location.getWorld().getName());
            pre.setString(3, String.valueOf(location.getX()));
            pre.setString(4, String.valueOf(location.getY()));
            pre.setString(5, String.valueOf(location.getZ()));
            pre.setString(6, String.valueOf(location.getYaw()));
            pre.setString(7, String.valueOf(location.getPitch()));
            if (pre.executeUpdate() == 0) {
                return false;
            }
        } catch (SQLException e) {
//            e.printStackTrace();
            return false;
        }
        return true;
    }

    public Map get(final String locationName) {
        final String sql = "SELECT * FROM tb_locations WHERE locationName = ?";
        ResultSet rs = null;
        final Map commandInfo = new HashMap();
        try {
            final PreparedStatement pre = this.query(sql);
            pre.setString(1, locationName);
            rs = pre.executeQuery();
            while (rs.next()) {
                commandInfo.put("locationName", rs.getString("locationName"));
                Location location = new Location(Bukkit.getWorld(rs.getString("worldName")),
                        Double.parseDouble(rs.getString("locationX")),
                        Double.parseDouble(rs.getString("locationY")),
                        Double.parseDouble(rs.getString("locationZ")),
                        Float.parseFloat(rs.getString("locationYaw")),
                        Float.parseFloat(rs.getString("locationPitch")));
                commandInfo.put("location", location);
            }
        } catch (Exception e) {
//            e.printStackTrace();
            return null;
        }
        return commandInfo;
    }

    public boolean remove(final String locationName) {
        final String sql = "DELETE FROM tb_locations WHERE locationName = ?";
        try {
            final PreparedStatement pre = this.query(sql);
            pre.setString(1, locationName);
            if (pre.executeUpdate() == 0) {
                return false;
            }
        } catch (SQLException e) {
//            e.printStackTrace();
            return false;
        }
        return true;
    }
}
